// 库文件
#include <stdio.h>
#include <string.h>
// 自定义文件
#include "sx1268.h"

// AT指令响应时间：ms
#define SX1268_AT_TIMEOUT 5

/* IO操作 */
#define SX1268_AT(x)                                                               \
    do                                                                             \
    {                                                                              \
        x ? HAL_GPIO_WritePin(SX1268_AT_GPIO_Port, SX1268_AT_Pin, GPIO_PIN_SET)    \
          : HAL_GPIO_WritePin(SX1268_AT_GPIO_Port, SX1268_AT_Pin, GPIO_PIN_RESET); \
    } while (0)

#define SX1268_WP(x)                                                               \
    do                                                                             \
    {                                                                              \
        x ? HAL_GPIO_WritePin(SX1268_WP_GPIO_Port, SX1268_WP_Pin, GPIO_PIN_SET)    \
          : HAL_GPIO_WritePin(SX1268_WP_GPIO_Port, SX1268_WP_Pin, GPIO_PIN_RESET); \
    } while (0)

#define SX1268_RESET(x)                                                                  \
    do                                                                                   \
    {                                                                                    \
        x ? HAL_GPIO_WritePin(SX1268_RESET_GPIO_Port, SX1268_RESET_Pin, GPIO_PIN_SET)    \
          : HAL_GPIO_WritePin(SX1268_RESET_GPIO_Port, SX1268_RESET_Pin, GPIO_PIN_RESET); \
    } while (0)

extern UART_HandleTypeDef huart1;

// AT测试指令
const char *kSX1268CmdAT = "AT\r\n";
const char *kSX1268CmdNodetoNode = "AT+NET=%s\r\n";

const char *kSX1268CmdTFreq = "AT+TFREQ=%x\r\n"; // 19CF0E40,433M

const char *kSX1268CmdRFreq = "AT+RFREQ=%x\r\n";
const char *kSX1268CmdRiq = "AT+RIQ=%s\r\n";
const char *kSX1268CmdCfg = "AT+CFG?\r\n";
const char *kSX1268CmdATT = "ATT\r\n";

extern uint16_t g_sx1268lastRxCount;

// 初始化LoRa模块
void SX1268_Init(void)
{
    SX1268_NET_MODE netMode = SX1268_NODE_TO_NODE;
    float tFreq = 433.0; // 433M
    float rFreq = 433.0; // 433M
    SX1268_RIQ_MODE riqMode = SX1268_RIQ_NO_REVERSE;
    printf("SX1268_Init\r\n");
    // 配置模式
    SX1268_ConfigMode();
    HAL_Delay(500);
    SX1268_ATTest();
    HAL_Delay(500);
    SX1268_ConfigNetMode(netMode);
    HAL_Delay(500);
    SX1268_ConfigTFreq(tFreq);
    HAL_Delay(500);
    SX1268_ConfigRFreq(rFreq);
    HAL_Delay(500);
    SX1268_ConfigRiq(riqMode);
    HAL_Delay(500);
    SX1268_ConfigCfgInfo();
}

// LoRa进入配置模式
void SX1268_ConfigMode(void)
{
    // AT=1为配置模式
    printf("sx1268 config reset\r\n");
    SX1268_RESET(0);
    HAL_Delay(20);
    SX1268_RESET(1);
    SX1268_WP(1);
    HAL_Delay(500);
    SX1268_WP(0);
    SX1268_AT(1);
    HAL_Delay(1000);
    uint8_t *result = NULL;
    result = SX1268_UART_Receive();
    if (result != NULL)
    {
        printf("wp info = %s\r\n", result);
    }
}

// LoRa进入通信模式
void SX1268_CommunicationMode(void)
{
    // AT =0为通信模式
    HAL_Delay(500);
    SX1268_AT(0);
    // SX1268_ConfigATT();
}

// 发送AT指令
uint8_t *SX1268_SendAtCMD(const char *cmd, uint32_t timeout)
{
    uint16_t len = strlen(cmd);
    HAL_UART_Transmit(&huart1, (uint8_t *)cmd, len, HAL_MAX_DELAY);
    uint8_t *result = NULL;
    while (timeout > 0)
    {
        HAL_Delay(500);
        result = SX1268_UART_Receive();
        if (g_sx1268lastRxCount != 0)
        {
            return result;
        }
        timeout--;
    }
    return NULL;
}

// 透明传输模式下：发送数据
void SX1268_SendData(const uint8_t *data)
{
    uint16_t len = strlen((char *)data);
    if (len > SX1268_UART_TX_BUFFER_SIZE)
    {
        printf("SX1268_SendData message too long\r\n");
        return;
    }
    // printf("SX1278_TTModeSendData length=%d,data=%s\r\n", len, data);
    HAL_UART_Transmit(&huart1, data, len, HAL_MAX_DELAY);
}

// AT测试
void SX1268_ATTest(void)
{
    uint8_t *result = SX1268_SendAtCMD(kSX1268CmdAT, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("ATtest result = %s\r\n", result);
    }
    else
    {
        printf("ATTest fail\r\n");
    }
}

// nodetonode
void SX1268_ConfigNetMode(SX1268_NET_MODE mode)
{
    char buf[SX1268_UART_RX_BUFFER_SIZE] = {0};
    sprintf(buf, kSX1268CmdNodetoNode, (mode ? "01" : "00"));
    uint8_t *result = SX1268_SendAtCMD(buf, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("ConfigNetModeresult = %s\r\n", result);
    }
    else
    {
        printf("ConfigNetMode fail\r\n");
    }
}

void SX1268_ConfigTFreq(float tFreq)
{
    char buf[SX1268_UART_RX_BUFFER_SIZE] = {0};
    // char tbuf[32] = {0};
    uint32_t temp = tFreq * 1000 * 1000;

    sprintf(buf, kSX1268CmdTFreq, temp);
    uint8_t *result = SX1268_SendAtCMD(buf, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("TFreq result = %s\r\n", result);
    }
    else
    {
        printf("ConfigTFreq fail\r\n");
    }
}

void SX1268_ConfigRFreq(float rFreq)
{
    char buf[SX1268_UART_RX_BUFFER_SIZE] = {0};
    uint32_t temp = rFreq * 1000 * 1000;
    sprintf(buf, kSX1268CmdRFreq, temp);
    uint8_t *result = SX1268_SendAtCMD(buf, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("RFreq result = %s\r\n", result);
    }
    else
    {
        printf("ConfigRFreq fail\r\n");
    }
}

void SX1268_ConfigCfgInfo(void)
{
    char buf[SX1268_UART_RX_BUFFER_SIZE] = {0};
    sprintf(buf, kSX1268CmdCfg);
    uint8_t *result = SX1268_SendAtCMD(buf, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("cfginfo result = %s\r\n", result);
    }
    else
    {
        printf("ConfigCfgInfo fail\r\n");
    }
}

void SX1268_ConfigRiq(SX1268_RIQ_MODE riqMode)
{
    char buf[SX1268_UART_RX_BUFFER_SIZE] = {0};
    sprintf(buf, kSX1268CmdRiq, (riqMode ? "01" : "00"));
    uint8_t *result = SX1268_SendAtCMD(buf, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("Riq result = %s\r\n", result);
    }
    else
    {
        printf("Riq fail\r\n");
    }
}

void SX1268_ConfigATT(void)
{
    char buf[SX1268_UART_RX_BUFFER_SIZE] = {0};
    sprintf(buf, kSX1268CmdATT);
    printf("ATT = %s\r\n", buf);
    uint8_t *result = SX1268_SendAtCMD(buf, SX1268_AT_TIMEOUT);
    if (result != NULL)
    {
        printf("ATT result = %s\r\n", result);
    }
    else
    {
        printf("ATT fail\r\n");
    }
}
